﻿using Autoverwaltung.GUI.ViewManager;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Autoverwaltung.GUI.ViewManager.Views
{
    /// <summary>
    /// Interaktionslogik für MainView.xaml
    /// </summary>
    public partial class MainView : UserControl, IView, Fachkonzept.IUserInterface
    {
        private readonly Fachkonzept.Fachkonzept fachkonzept;
        private bool isBlocked = false;

        #region Implement IView
        public event EventHandler<ChangeAnsichtEventArgs> ChangeAnsicht;

        public bool IsLocked
        {
            get { return isBlocked; }
        }

        public UIElement UIElement
        {
            get { return this; }
        }
        #endregion

        public MainView()
        {
            InitializeComponent();

            this.fachkonzept = Fachkonzept.Fachkonzept.GetInstance(this);

            this.Loaded += MainView_Loaded;

            //this.FillCarModelsList(this.fachkonzept.GibModelle());
            //this.FillModelManufacturersList(this.fachkonzept.GibHersteller());

            this.lbxManufacturer.SelectionChanged += lbxManufacturer_SelectionChanged;
            this.lbxModels.SelectionChanged += lbxModels_SelectionChanged;
            this.dgdCars.SelectionChanged += dgdCars_SelectionChanged;
        }

        void MainView_Loaded(object sender, RoutedEventArgs e)
        {
            //this.FillManufacturerList(this.fachkonzept.GibHersteller());
            this.AktualisiereDaten();
        }

        #region Aktualisiere Daten
        private void AktualisiereDaten()
        {
            this.AktualisiereHerstellerDaten();
            this.AktualisiereModelleDaten();
            this.AktualisiereAutoDaten();
        }
        
        private T SelectedItemTagObjectHelper<T>(object obj)
        {
            FrameworkElement elem = obj as FrameworkElement;
            if (elem != null)
            {
                try
                {
                    return (T)elem.Tag;
                }
                catch { }
            }

            return default(T);
        }

        #region Aktualisiere Hersteller Daten
        private void AktualisiereHerstellerDaten(Model.Hersteller ausgewaehlterHersteller = null)
        {
            this.AktualisiereHerstellerListe(ausgewaehlterHersteller);
            this.AktualisiereModellHerstellerAuswahl();
        }

        private void AktualisiereHerstellerListe(Model.Hersteller ausgewaehlterHersteller = null)
        {
            Model.Hersteller item = this.SelectedItemTagObjectHelper<Model.Hersteller>(this.lbxManufacturer.SelectedIndex);
            this.lbxManufacturer.Items.Clear();
            this.lbxManufacturer.Items.Add(new ListBoxItem() { Content = "Alle" });

            foreach (Model.Hersteller h in this.fachkonzept.GibHersteller())
            {
                ListBoxItem lbi = new ListBoxItem() { Content = h.Name, Tag = h };
                this.lbxManufacturer.Items.Add(lbi);
            }

            this.lbxManufacturer.SelectedItem = 0;

            if (ausgewaehlterHersteller != null)
            {
                this.SelectHersteller(ausgewaehlterHersteller);
            }
            else
            {
                foreach (object obj in this.lbxManufacturer.Items)
                {
                    Model.Hersteller h = this.SelectedItemTagObjectHelper<Model.Hersteller>(obj);

                    if (h != null && h.Equals(item))
                    {
                        this.lbxManufacturer.SelectedItem = obj;
                        break;
                    }
                }

                if (this.lbxManufacturer.SelectedIndex < 0)
                {
                  this.lbxManufacturer.SelectedIndex = 0;
                }
            }
        }

        private void AktualisiereModellHerstellerAuswahl()
        {
            Model.Hersteller item = this.SelectedItemTagObjectHelper<Model.Hersteller>(this.cbxModelManufacturer.SelectedItem);
            this.cbxModelManufacturer.Items.Clear();

            foreach (Model.Hersteller h in this.fachkonzept.GibHersteller())
            {
                ComboBoxItem cbi = new ComboBoxItem() { Content = h.Name, Tag = h };
                this.cbxModelManufacturer.Items.Add(cbi);
            }

            foreach (object obj in this.cbxModelManufacturer.Items)
            {
                Model.Hersteller h = this.SelectedItemTagObjectHelper<Model.Hersteller>(obj);

                if(h != null && h.Equals(item))
                {
                    this.cbxModelManufacturer.SelectedItem = obj;
                    break;
                }
            }
        }
        #endregion

        #region Aktualisiere Modell Daten
        private void AktualisiereModelleDaten(Model.Modell ausgewaehltesModell = null)
        {
            this.AktualisiereModelleListe(ausgewaehltesModell);
            this.AktualisiereAutoModelleAuswahl();
        }

        private void AktualisiereModelleListe(Model.Modell ausgewaehltesModell = null)
        {
            ListBoxItem lbiManufacturer = this.lbxManufacturer.SelectedItem as ListBoxItem;
            
            Model.Modell[] modelle = null;
            if (lbiManufacturer != null && lbiManufacturer.Tag != null && lbiManufacturer.Tag is Model.Hersteller)
            {
                modelle = this.fachkonzept.GibModelleNach(lbiManufacturer.Tag as Model.Hersteller);
            }
            else
            {
                modelle = this.fachkonzept.GibModelle();
            }

            Model.Modell item = this.SelectedItemTagObjectHelper<Model.Modell>(this.lbxModels.SelectedItem);
            this.lbxModels.Items.Clear();
            this.lbxModels.Items.Add(new ListBoxItem() { Content = "Alle" });

            foreach (Model.Modell m in modelle)
            {
                ListBoxItem lbi = new ListBoxItem() { Content = m.Bezeichnung, Tag = m };
                this.lbxModels.Items.Add(lbi);
            }

            this.lbxModels.SelectedIndex = 0;


            if (ausgewaehltesModell != null)
            {
                this.SelectModell(ausgewaehltesModell);
            }
            else
            {
                foreach (object obj in this.lbxModels.Items)
                {
                    Model.Modell m = this.SelectedItemTagObjectHelper<Model.Modell>(obj);

                    if (m != null && m.Equals(item))
                    {
                        this.lbxModels.SelectedItem = obj;
                        break;
                    }
                }

                if (this.lbxModels.SelectedIndex < 0)
                {
                  this.lbxModels.SelectedIndex = 0;
                }
            }
        }

        private void AktualisiereAutoModelleAuswahl()
        {
            Model.Modell item = this.SelectedItemTagObjectHelper<Model.Modell>(this.cbxCarAllModels.SelectedItem);

            this.cbxCarAllModels.Items.Clear();

            foreach (Model.Modell m in this.fachkonzept.GibModelle())
            {
                ComboBoxItem cbi = new ComboBoxItem() { Content = m.Bezeichnung, Tag = m };
                this.cbxCarAllModels.Items.Add(cbi);
            }
            
            foreach (object obj in this.cbxCarAllModels.Items)
            {
                Model.Modell m = this.SelectedItemTagObjectHelper<Model.Modell>(obj);

                if (m != null && m.Equals(item))
                {
                    this.cbxCarAllModels.SelectedItem = obj;
                    break;
                }
            }
        }
        #endregion

        #region Aktualisiere Auto Daten
        private void AktualisiereAutoDaten(Model.Auto ausgewaehltesAuto = null)
        {
            this.AktualisiereAutoListe(ausgewaehltesAuto);
        }

        private void AktualisiereAutoListe(Model.Auto ausgewaehltesAuto = null)
        {
            object item = this.dgdCars.SelectedItem;

            ListBoxItem lbiManufacturer = this.lbxManufacturer.SelectedItem as ListBoxItem;
            ListBoxItem lbiModel = this.lbxModels.SelectedItem as ListBoxItem;
            if (lbiModel != null && lbiModel.Tag != null && lbiModel.Tag is Model.Modell)
            {
                this.dgdCars.ItemsSource = this.fachkonzept.GibAutosNach(lbiModel.Tag as Model.Modell);
            }
            else if (lbiManufacturer != null && lbiManufacturer.Tag != null && lbiManufacturer.Tag is Model.Hersteller)
            {
                this.dgdCars.ItemsSource = this.fachkonzept.GibAutosNach(lbiManufacturer.Tag as Model.Hersteller);
            }
            else
            {
                this.dgdCars.ItemsSource = this.fachkonzept.GibAutos();
            }

            if (ausgewaehltesAuto != null)
            {
                this.SelectCar(ausgewaehltesAuto);
            }
            else
            {
                this.dgdCars.SelectedItem = item;
            }
        }
        #endregion
        #endregion

        #region Select objects in lists and so on
        private void SelectHersteller(Model.Hersteller hersteller)
        {
            if (hersteller == null)
            {
                this.lbxManufacturer.SelectedIndex = 0;
                return;
            }

            foreach (object obj in this.lbxManufacturer.Items)
            {
                ListBoxItem lbi = obj as ListBoxItem;

                if (lbi != null)
                {
                    Model.Hersteller h = lbi.Tag as Model.Hersteller;

                    if (h != null && h.Equals(hersteller))
                    {
                        this.lbxManufacturer.SelectedItem = obj;
                        break;
                    }
                }
            }
        }

        private void SelectModell(Model.Modell modell)
        {
            if (modell == null)
            {
                this.lbxModels.SelectedIndex = 0;
                return;
            }

            foreach (object obj in this.lbxModels.Items)
            {
                ListBoxItem lbi = obj as ListBoxItem;

                if (lbi != null)
                {
                    Model.Modell m = lbi.Tag as Model.Modell;

                    if (m != null && m.Equals(modell))
                    {
                        this.lbxModels.SelectedItem = obj;
                        break;
                    }
                }
            }
        }

        private void SelectModelManufacturer(Model.Hersteller hersteller)
        {
            if (hersteller == null)
            {
                this.cbxModelManufacturer.SelectedIndex = -1;
                return;
            }

            foreach (object obj in this.cbxModelManufacturer.Items)
            {
                ComboBoxItem cbi = obj as ComboBoxItem;

                if (cbi != null)
                {
                    Model.Hersteller h = cbi.Tag as Model.Hersteller;

                    if (h != null && h.Equals(hersteller))
                    {
                        this.cbxModelManufacturer.SelectedItem = obj;
                        break;
                    }
                }
            }
        }

        private void SelectCarModel(Model.Modell modell)
        {
            foreach (object obj in this.cbxCarAllModels.Items)
            {
                ComboBoxItem cbi = obj as ComboBoxItem;

                if (cbi != null)
                {
                    Model.Modell m = cbi.Tag as Model.Modell;

                    if (m != null && m.Equals(modell))
                    {
                        this.cbxCarAllModels.SelectedItem = obj;
                        break;
                    }
                }
            }
        }

        private void SelectCar(Model.Auto auto)
        {
            foreach (object obj in this.dgdCars.Items)
            {
                Model.Auto a = obj as Model.Auto;

                if (a.Id == auto.Id)
                {
                    this.dgdCars.SelectedItem = obj;
                }
            }
        }
        #endregion

        #region Selection Changed
        bool lbxManufacturerRewinding = false;
        void lbxManufacturer_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbxManufacturerRewinding)
            {
                return;
            }

            //if (this.ContinueCheck(ref this.manufacturerChangesSaved) && this.ContinueCheck(ref this.modelChangesSaved) && this.ContinueCheck(ref this.carChangesSaved))
            if(this.manufacturerChangesSaved && this.modelChangesSaved && this.carChangesSaved)
            {
                Model.Hersteller manufacturer = null;
                ListBoxItem lbi = this.lbxManufacturer.SelectedItem as ListBoxItem;
                if (lbi != null)
                {
                    manufacturer = lbi.Tag as Model.Hersteller;
                }
                this.CurrentlyActiveManufacturer = manufacturer;
            }
            else
            {
                this.lbxManufacturerRewinding = true;
                if (this.lbxManufacturer.SelectionMode != SelectionMode.Single)
                {
                    foreach (object obj in e.AddedItems)
                    {
                        this.lbxManufacturer.SelectedItems.Remove(obj);
                    }

                    foreach (object obj in e.RemovedItems)
                    {
                        this.lbxManufacturer.SelectedItems.Add(obj);
                    }
                }
                else
                {
                    this.lbxManufacturer.SelectedItem = (e.RemovedItems.Count > 0) ? e.RemovedItems[0] : null;
                }
                this.lbxManufacturerRewinding = false;
            }
        }
        
        bool lbxModelsRewinding = false;
        void lbxModels_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lbxModelsRewinding)
            {
                return;
            }

            //if (this.ContinueCheck(ref this.manufacturerChangesSaved) && this.ContinueCheck(ref this.modelChangesSaved) && this.ContinueCheck(ref this.carChangesSaved))
            if (this.manufacturerChangesSaved && this.modelChangesSaved && this.carChangesSaved)
            {
                Model.Modell modell = null;
                ListBoxItem lbi = this.lbxModels.SelectedItem as ListBoxItem;
                if (lbi != null)
                {
                    modell = lbi.Tag as Model.Modell;
                }
                this.CurrentlyActiveModel = modell;
            }
            else
            {
                this.lbxModelsRewinding = true;
                if (this.lbxModels.SelectionMode != SelectionMode.Single)
                {
                    foreach (object obj in e.AddedItems)
                    {
                        this.lbxModels.SelectedItems.Remove(obj);
                    }

                    foreach (object obj in e.RemovedItems)
                    {
                        this.lbxModels.SelectedItems.Add(obj);
                    }
                }
                else
                {
                    this.lbxModels.SelectedItem = (e.RemovedItems.Count > 0) ? e.RemovedItems[0] : null;
                }
                this.lbxModelsRewinding = false;
            }
        }

        bool dgdCarsRewinding = false;
        void dgdCars_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (dgdCarsRewinding)
            {
                return;
            }

            //if (this.ContinueCheck(ref this.manufacturerChangesSaved) && this.ContinueCheck(ref this.modelChangesSaved) && this.ContinueCheck(ref this.carChangesSaved))
            if (this.manufacturerChangesSaved && this.modelChangesSaved && this.carChangesSaved)
            {
                Model.Auto car = this.dgdCars.SelectedItem as Model.Auto;
                this.CurrentlyActiveCar = car;
            }
            else
            {
                this.dgdCarsRewinding = true;
                if (this.dgdCars.SelectionMode != DataGridSelectionMode.Single)
                {
                    foreach (object obj in e.AddedItems)
                    {
                        this.dgdCars.SelectedItems.Remove(obj);
                    }

                    foreach (object obj in e.RemovedItems)
                    {
                        this.dgdCars.SelectedItems.Add(obj);
                    }
                }
                else
                {
                    this.dgdCars.SelectedItem = (e.RemovedItems.Count > 0) ? e.RemovedItems[0] : null;
                }
                this.dgdCarsRewinding = false;
            }
        }
        #endregion

        #region Refresh lists and so on
        /*private void RefreshManufacturerList(Model.Hersteller select = null)
        {
            int index = this.lbxManufacturer.SelectedIndex;

            this.CurrentlyActiveCar = null;
            this.FillManufacturerList(this.fachkonzept.GibHersteller());

            if (select != null)
            {
                this.SelectHersteller(select);
            }
            else
            {
                this.lbxManufacturer.SelectedIndex = index;
            }
        }

        private void RefreshModelList(Model.Modell select = null)
        {
            this.CurrentlyActiveCar = null;
            ListBoxItem lbi = this.lbxManufacturer.SelectedItem as ListBoxItem;

            int index = this.lbxModels.SelectedIndex;

            if (lbi != null && lbi.Tag != null && lbi.Tag is Model.Hersteller)
            {
                this.FillModelList(this.fachkonzept.GibModelleNach(lbi.Tag as Model.Hersteller));
            }
            else
            {
                this.FillModelList(this.fachkonzept.GibModelle());
            }

            if (select != null)
            {
                this.SelectModell(select);
            }
            else
            {
                this.lbxModels.SelectedIndex = index;
            }
        }

        private void RefreshCarList(Model.Auto select = null)
        {
            int index = this.dgdCars.SelectedIndex;

            this.CurrentlyActiveCar = null;
            ListBoxItem lbiManufacturer = this.lbxManufacturer.SelectedItem as ListBoxItem;
            ListBoxItem lbiModel = this.lbxModels.SelectedItem as ListBoxItem;
            if (lbiModel != null && lbiModel.Tag != null && lbiModel.Tag is Model.Modell)
            {
                this.FillCarDataSet(this.fachkonzept.GibAutosNach(lbiModel.Tag as Model.Modell));
            }
            else if (lbiManufacturer != null && lbiManufacturer.Tag != null && lbiManufacturer.Tag is Model.Hersteller)
            {
                this.FillCarDataSet(this.fachkonzept.GibAutosNach(lbiManufacturer.Tag as Model.Hersteller));
            }
            else
            {
                this.FillCarDataSet(this.fachkonzept.GibAutos());
            }

            if (select != null)
            {
                this.SelectCar(select);
            }
            else
            {
                this.dgdCars.SelectedIndex = index;
            }
        }
        */
        #endregion

        #region Fill lists and so on with actual data
        /*private void FillCarModelsList(Model.Modell[] modell)
        {
            this.cbxCarAllModels.Items.Clear();

            foreach (Model.Modell m in modell)
            {
                ComboBoxItem cbi = new ComboBoxItem() { Content = m.Bezeichnung, Tag = m };
                this.cbxCarAllModels.Items.Add(cbi);
            }
        }

        private void FillModelManufacturersList(Model.Hersteller[] manufacturer)
        {
            this.cbxModelManufacturer.Items.Clear();

            foreach (Model.Hersteller h in manufacturer)
            {
                ComboBoxItem cbi = new ComboBoxItem() { Content = h.Name, Tag = h };
                this.cbxModelManufacturer.Items.Add(cbi);
            }
        }

        private ListBoxItem CreateAllElement()
        {
            return new ListBoxItem() { Content = "Alle" };
        }

        private void FillManufacturerList(Model.Hersteller[] hersteller)
        {
            this.lbxManufacturer.Items.Clear();

            this.lbxManufacturer.Items.Add(this.CreateAllElement());

            foreach (Model.Hersteller h in hersteller)
            {
                ListBoxItem lbi = new ListBoxItem() { Content = h.Name, Tag = h };
                this.lbxManufacturer.Items.Add(lbi);
            }

            this.lbxManufacturer.SelectedIndex = 0;
        }

        private void FillModelList(Model.Modell[] models)
        {
            this.lbxModels.Items.Clear();

            this.lbxModels.Items.Add(this.CreateAllElement());

            foreach (Model.Modell m in models)
            {
                ListBoxItem lbi = new ListBoxItem() { Content = m.Bezeichnung, Tag = m };
                this.lbxModels.Items.Add(lbi);
            }

            this.lbxModels.SelectedIndex = 0;
        }

        private void FillCarDataSet(Model.Auto[] auto)
        {
            this.dgdCars.ItemsSource = auto;
        }*/
        #endregion

        #region Handle left hand side expander
        private void expander_Expanded(object sender, RoutedEventArgs e)
        {
            if (sender == this.expManufacturer)
            {
                this.expModels.IsExpanded = false;
            }
            else if (sender == this.expModels)
            {
                this.expManufacturer.IsExpanded = false;
            }
        }
        #endregion

        #region Manufacturer choose, edit, delete, new
        private bool isManufacturerDataLoaded = false;
        private bool manufacturerChangesSaved = true;
        private Model.Hersteller currentlyActiveManufacturer;
        public Model.Hersteller CurrentlyActiveManufacturer
        {
            get { return this.currentlyActiveManufacturer; }
            set
            {
                if (this.manufacturerChangesSaved)
                {
                    this.manufacturerChangesSaved = true;
                    this.currentlyActiveManufacturer = value;
                    this.CurrentlyActiveManufacturerChanged(value);
                }
            }
        }

        private void CurrentlyActiveManufacturerChanged(Model.Hersteller hersteller)
        {
            this.isManufacturerDataLoaded = false;

            if (hersteller == null || hersteller != null && !hersteller.Id.Equals(int.MinValue))
            {
                this.AktualisiereModelleDaten();

                if (hersteller != null)
                {
                    this.expManufacturerEdit.IsExpanded = true;
                }
                else
                {
                    this.expManufacturerEdit.IsExpanded = false;
                }
            }
            
            this.tbxManufacturerName.IsEnabled = false;
            this.tbxManufacturerName.Text = null;

            this.btnManufacturerAbort.IsEnabled = false;
            this.btnManufacturerDelete.IsEnabled = false;
            this.btnManufacturerSave.IsEnabled = false;

            if (hersteller != null)
            {
                this.tbxManufacturerName.IsEnabled = true;
                this.tbxManufacturerName.Text = hersteller.Name;

                this.btnManufacturerAbort.IsEnabled = false;
                this.btnManufacturerDelete.IsEnabled = true;
                this.btnManufacturerSave.IsEnabled = false;
            }

            this.isManufacturerDataLoaded = true;
        }

        private void btnManufacturer_Click(object sender, RoutedEventArgs e)
        {
            if (sender == this.btnManufacturerNew)
            {
                if (this.ContinueCheck(ref this.manufacturerChangesSaved))
                {
                    this.CurrentlyActiveManufacturer = new Model.Hersteller() { Id = int.MinValue };
                    this.tbxManufacturerName.IsEnabled = true;
                    this.manufacturerChangesSaved = false;
                    this.btnManufacturerAbort.IsEnabled = true;
                    this.btnManufacturerDelete.IsEnabled = false;
                    this.btnManufacturerSave.IsEnabled = true;
                }
            }
            else if (sender == this.btnManufacturerDelete)
            {
                if (this.CurrentlyActiveManufacturer != null)
                {
                    if (this.ContinueCheck(ref this.manufacturerChangesSaved))
                    {
                        var res = MessageBox.Show("Möchten Sie den Hersteller wirklich löschen?", "Modell löschen", MessageBoxButton.YesNo,
                            MessageBoxImage.Warning, MessageBoxResult.No);

                        if (res == MessageBoxResult.Yes)
                        {
                            if (this.fachkonzept.LoescheHersteller(this.CurrentlyActiveManufacturer.Id))
                            {
                                //this.InformationDialog("Der Hersteller wurde erfolgreich gelöscht.", "Löschen erfolgreich");

                                //this.RefreshModelList();
                                //this.CurrentlyActiveManufacturer = null;
                                this.manufacturerChangesSaved = true;
                                this.AktualisiereHerstellerDaten();
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }

                this.InformationDialog("Der Hersteller konnte nicht gelöscht werden.", "Löschen fehlgeschlagen");
            }
            else if (sender == this.btnManufacturerAbort)
            {
                if (this.ContinueCheck(ref this.manufacturerChangesSaved))
                {
                    this.manufacturerChangesSaved = true;
                    this.CurrentlyActiveManufacturer = this.CurrentlyActiveManufacturer;
                }
            }
            else if (sender == this.btnManufacturerSave)
            {
                Model.Hersteller manufacturer = this.BuildManufacturer();

                if (this.CurrentlyActiveManufacturer != null && !this.CurrentlyActiveManufacturer.Id.Equals(int.MinValue))
                {
                    if (this.fachkonzept.BearbeiteHersteller(this.CurrentlyActiveManufacturer.Id, manufacturer))
                    {
                        this.manufacturerChangesSaved = true;
                        //this.RefreshManufacturerList(manufacturer);
                        this.AktualisiereHerstellerDaten(manufacturer);
                        //this.InformationDialog("Die Änderungen am Hersteller wurden erfolgreich übernommen.", "Speichern erfolgreich");
                    }
                    else
                    {
                        this.InformationDialog("Die Änderungen am Hersteller konnten nicht übernommen werden.", "Speichern fehlgeschlagen");
                    }
                }
                else
                {
                    if (this.fachkonzept.NeuerHersteller(manufacturer))
                    {
                        this.manufacturerChangesSaved = true;
                        this.SelectNewManufacturer(manufacturer);
                        //this.InformationDialog("Der Hersteller wurde erfolgreich gespeichert.", "Speichern erfolgreich");
                    }
                    else
                    {
                        this.InformationDialog("Der Hersteller konnte nicht gespeichert werden.", "Speichern fehlgeschlagen");
                    }
                }
            }
        }

        private void SelectNewManufacturer(Model.Hersteller hersteller)
        {
            if (hersteller != null)
            {
                //this.RefreshManufacturerList(hersteller);
                this.AktualisiereHerstellerDaten(hersteller);
            }
        }

        private void tbxManufacturerName_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.CheckIfActiveManufacturerDataChanged();
        }

        private void CheckIfActiveManufacturerDataChanged()
        {
            if (isManufacturerDataLoaded)
            {
                bool changed = false;

                Model.Hersteller manufacturer = this.BuildManufacturer();
                if (this.CurrentlyActiveManufacturer != null && !manufacturer.Equals(this.CurrentlyActiveManufacturer))
                {
                    changed = true;
                }

                this.manufacturerChangesSaved = !changed;
                this.btnManufacturerSave.IsEnabled = changed;
                this.btnManufacturerAbort.IsEnabled = changed;
            }
        }

        private Model.Hersteller BuildManufacturer()
        {
            string name = (this.tbxManufacturerName.Text == "") ? null : this.tbxManufacturerName.Text;

            Model.Hersteller hersteller = new Model.Hersteller()
            {
                Name = name
            };
            if (this.CurrentlyActiveManufacturer != null)
            {
                hersteller.Id = this.CurrentlyActiveManufacturer.Id;
            }
            return hersteller;
        }
        #endregion

        #region Model choose, edit, delete, new
        private bool isModelDataLoaded = false;
        private bool modelChangesSaved = true;
        private Model.Modell currentlyActiveModel;
        public Model.Modell CurrentlyActiveModel
        {
            get { return this.currentlyActiveModel; }
            set
            {
                if (modelChangesSaved)
                {
                    this.modelChangesSaved = true;
                    this.currentlyActiveModel = value;
                    this.CurrentlyActiveModelChanged(value);
                }
            }
        }

        private void CurrentlyActiveModelChanged(Model.Modell modell)
        {
            this.isModelDataLoaded = false;

            if (modell == null || modell != null && !modell.Id.Equals(int.MinValue))
            {
                this.AktualisiereAutoDaten();

                if (modell != null)
                {
                    this.expModelEdit.IsExpanded = true;
                }
                else
                {
                    this.expModelEdit.IsExpanded = false;
                }
            }

            this.tbxModelDescription.IsEnabled = false;
            this.cbxModelManufacturer.IsEnabled = false;

            this.cbxModelManufacturer.SelectedIndex = -1;
            this.tbxModelDescription.Text = null;

            this.btnModelAbort.IsEnabled = false;
            this.btnModelDelete.IsEnabled = false;
            this.btnModelSave.IsEnabled = false;

            if (modell != null)
            {
                this.tbxModelDescription.IsEnabled = true;
                this.cbxModelManufacturer.IsEnabled = true;
                this.SelectModelManufacturer(modell.Hersteller);
                this.tbxModelDescription.Text = modell.Bezeichnung;

                this.btnModelDelete.IsEnabled = true;
                this.btnModelAbort.IsEnabled = false;
                this.btnModelSave.IsEnabled = false;
            }

            this.isModelDataLoaded = true;
        }

        private void btnModel_Click(object sender, RoutedEventArgs e)
        {
            if (sender == this.btnModelNew)
            {
                if (this.ContinueCheck(ref this.modelChangesSaved))
                {
                    this.CurrentlyActiveModel = new Model.Modell() { Id = int.MinValue };
                    this.tbxModelDescription.IsEnabled = true;
                    this.cbxModelManufacturer.IsEnabled = true;
                    this.modelChangesSaved = false;
                    this.btnModelAbort.IsEnabled = true;
                    this.btnModelDelete.IsEnabled = false;
                    this.btnModelSave.IsEnabled = true;
                }
            }
            else if (sender == this.btnModelDelete)
            {
                if (this.currentlyActiveModel != null)
                {
                    if (this.ContinueCheck(ref this.modelChangesSaved))
                    {
                        var res = MessageBox.Show("Möchten Sie das Modell wirklich löschen?", "Modell löschen", MessageBoxButton.YesNo,
                            MessageBoxImage.Warning, MessageBoxResult.No);

                        if (res == MessageBoxResult.Yes)
                        {
                            if (this.fachkonzept.LoescheModell(this.currentlyActiveModel.Id))
                            {
                                //this.InformationDialog("Das Modell wurde erfolgreich gelöscht.", "Löschen erfolgreich");

                                //this.RefreshModelList();
                                this.modelChangesSaved = true;
                                this.AktualisiereModelleDaten();
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }

                this.InformationDialog("Das Modell konnte nicht gelöscht werden.", "Löschen fehlgeschlagen");
            }
            else if (sender == this.btnModelAbort)
            {
                if (this.ContinueCheck(ref this.modelChangesSaved))
                {
                    this.modelChangesSaved = true;
                    this.CurrentlyActiveModel = this.CurrentlyActiveModel;
                }
            }
            else if (sender == this.btnModelSave)
            {
                Model.Modell modell = this.BuildModell();

                if (this.CurrentlyActiveModel != null && !this.CurrentlyActiveModel.Id.Equals(int.MinValue))
                {
                    if (this.fachkonzept.BearbeiteModell(this.CurrentlyActiveModel.Id, modell))
                    {
                        this.modelChangesSaved = true;
                        //this.RefreshModelList(modell);
                        this.AktualisiereModelleDaten(modell);
                        //this.InformationDialog("Die Änderungen am Modell wurden erfolgreich übernommen.", "Speichern erfolgreich");
                    }
                    else
                    {
                        this.InformationDialog("Die Änderungen am Modell konnten nicht übernommen werden.", "Speichern fehlgeschlagen");
                    }
                }
                else
                {
                    if (this.fachkonzept.NeuesModell(modell))
                    {
                        this.modelChangesSaved = true;
                        this.SelectNewModel(modell);
                        //this.InformationDialog("Das Modell wurde erfolgreich gespeichert.", "Speichern erfolgreich");
                    }
                    else
                    {
                        this.InformationDialog("Das Modell konnte nicht gespeichert werden.", "Speichern fehlgeschlagen");
                    }
                }
            }
        }

        private void SelectNewModel(Model.Modell modell)
        {
            if (modell != null)
            {
                this.SelectHersteller(modell.Hersteller);
                //this.RefreshModelList(modell);
                this.AktualisiereModelleDaten(modell);
            }
        }

        private void tbxModelDescription_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.CheckIfActiveModelDataChanged();
        }

        private void cbxModelManufacturer_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.CheckIfActiveModelDataChanged();
        }

        private void CheckIfActiveModelDataChanged()
        {
            if (isModelDataLoaded)
            {
                bool changed = false;

                Model.Modell modell = this.BuildModell();
                if (this.CurrentlyActiveModel != null && !modell.Equals(this.CurrentlyActiveModel))
                {
                    changed = true;
                }

                this.modelChangesSaved = !changed;
                this.btnModelSave.IsEnabled = changed;
                this.btnModelAbort.IsEnabled = changed;
            }
        }

        private Model.Modell BuildModell()
        {
            string bezeichnung = (this.tbxModelDescription.Text == "") ? null : this.tbxModelDescription.Text;
            Model.Hersteller hersteller = null;

            if(this.cbxModelManufacturer.SelectedItem is ComboBoxItem)
            {
                hersteller = (this.cbxModelManufacturer.SelectedItem as ComboBoxItem).Tag as Model.Hersteller;
            }

            Model.Modell modell = new Model.Modell()
            {
                Bezeichnung = bezeichnung,
                Hersteller = hersteller
            };

            if (this.CurrentlyActiveModel != null)
            {
                modell.Id = this.CurrentlyActiveModel.Id;
            }

            return modell;
        }
        #endregion

        #region Car choose, edit, delete, new
        private bool isCarDataLoaded = false;
        private bool carChangesSaved = true;
        private Model.Auto currentlyActiveCar;
        public Model.Auto CurrentlyActiveCar
        {
            get { return this.currentlyActiveCar; }
            set
            {
                if (this.carChangesSaved)
                {
                    this.carChangesSaved = true;
                    this.currentlyActiveCar = value;
                    this.CurrentlyActiveCarChanged(value);
                }
            }
        }

        private void CurrentlyActiveCarChanged(Model.Auto auto)
        {
            this.isCarDataLoaded = false;

            this.grdCarEdit.IsEnabled = false;
            this.cbxCarAllModels.SelectedIndex = -1;

            this.ccCarColorCanvas.SelectedColor = Colors.Black;
            this.iudCarPower.Value = null;
            this.iudCarCubicCapacity.Value = null;
            this.lblCarManufaturer.Content = null;
            this.iudCarCylinder.Value = null;
            this.tbxCarFuel.Text = null;
            this.dudCarFuelCityConsumption.Value = null;
            this.dudCarFuelOutOfTownConsumption.Value = null;
            this.lblCarFuelConsumptionCombined.Content = null;

            this.btnCarDelete.IsEnabled = false;
            this.btnCarAbort.IsEnabled = false;
            this.btnCarDelete.IsEnabled = false;
            this.btnCarSaveChanges.IsEnabled = false;

            if (auto != null)
            {
                this.grdCarEdit.IsEnabled = true;
                this.ccCarColorCanvas.SelectedColor = Color.FromArgb(255, auto.Farbe.R, auto.Farbe.G, auto.Farbe.B);
                if (auto.Modell != null && auto.Modell.Hersteller != null)
                {
                    this.lblCarManufaturer.Content = auto.Modell.Hersteller.Name;
                }
                this.SelectCarModel(auto.Modell);
                this.iudCarPower.Value = auto.Leistung;
                this.iudCarCubicCapacity.Value = auto.Hubraum;
                this.iudCarCylinder.Value = auto.Zylinder;
                this.tbxCarFuel.Text = auto.Kraftstoff;
                if (auto.Verbrauch != null)
                {
                    this.dudCarFuelCityConsumption.Value = auto.Verbrauch.Innerorts;
                    this.dudCarFuelOutOfTownConsumption.Value = auto.Verbrauch.Ausserorts;
                }
                this.btnCarDelete.IsEnabled = true;
                this.btnCarAbort.IsEnabled = false;
                this.btnCarSaveChanges.IsEnabled = false;
            }
            else
            {
                this.cbxCarAllModels.SelectedIndex = -1;
            }

            this.isCarDataLoaded = true;
        }

        private void ccCarColorCanvas_SelectedColorChanged(object sender, RoutedPropertyChangedEventArgs<Color> e)
        {
            this.CheckIfActiveCarDataChanged();
        }

        private void cbxCarAllModels_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
          this.lblCarManufaturer.Content = null;
          ComboBoxItem cbi = this.cbxCarAllModels.SelectedItem as ComboBoxItem;
          if (cbi != null)
          {
            var modell = cbi.Tag as Model.Modell;
            if (modell != null && modell.Hersteller != null)
            {
              this.lblCarManufaturer.Content = modell.Hersteller.Name;
            }            
          }

            this.CheckIfActiveCarDataChanged();
        }

        private void car_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (sender == this.dudCarFuelCityConsumption || sender == this.dudCarFuelOutOfTownConsumption)
            {
                if (this.dudCarFuelCityConsumption.Value.HasValue && this.dudCarFuelOutOfTownConsumption.Value.HasValue)
                {
                    this.lblCarFuelConsumptionCombined.Content = new Model.Verbrauch()
                    {
                        Innerorts = this.dudCarFuelCityConsumption.Value.Value,
                        Ausserorts = this.dudCarFuelOutOfTownConsumption.Value.Value
                    }.Kombiniert.ToString("0.00");
                }
            }

            this.CheckIfActiveCarDataChanged();
        }

        private void cbxFuels_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.CheckIfActiveCarDataChanged();
        }

        private void tbxCarFuel_TextChanged(object sender, TextChangedEventArgs e)
        {
            this.CheckIfActiveCarDataChanged();
        }

        private void CheckIfActiveCarDataChanged()
        {
            if (this.isCarDataLoaded)
            {
                bool changed = false;

                Model.Auto car = this.BuildCar();
                if (this.CurrentlyActiveCar != null && !car.Equals(this.CurrentlyActiveCar))
                {
                    changed = true;
                }

                this.carChangesSaved = !changed;
                this.btnCarSaveChanges.IsEnabled = changed;
                this.btnCarAbort.IsEnabled = changed;
            }
        }

        private Model.Auto BuildCar()
        {
            Model.Modell modell = null;
            int leistung = (this.iudCarPower.Value != null) ? this.iudCarPower.Value.Value : 0;
            int hubraum = (this.iudCarCubicCapacity.Value != null) ? this.iudCarCubicCapacity.Value.Value : 0;
            int zylinder = (this.iudCarCylinder.Value != null) ? this.iudCarCylinder.Value.Value : 0;
            decimal verbrauchInnerorts = (this.dudCarFuelCityConsumption.Value.HasValue) ? this.dudCarFuelCityConsumption.Value.Value : 0;
            decimal verbrauchAusserorts = (this.dudCarFuelOutOfTownConsumption.Value.HasValue) ? this.dudCarFuelOutOfTownConsumption.Value.Value : 0;
            var c = this.ccCarColorCanvas.SelectedColor;
            System.Drawing.Color farbe = System.Drawing.Color.FromArgb(255, c.R, c.G, c.B);
            string kraftstoff = (this.tbxCarFuel.Text == "") ? null : this.tbxCarFuel.Text;

            ComboBoxItem cbi = this.cbxCarAllModels.SelectedItem as ComboBoxItem;
            if (cbi != null)
            {
                if (cbi.Tag is Model.Modell)
                {
                    modell = cbi.Tag as Model.Modell;
                }
            }

            Model.Auto car = new Model.Auto();
            if (this.CurrentlyActiveCar != null)
            {
                car.Id = this.CurrentlyActiveCar.Id;
            }

            car.Modell = modell;
            car.Kraftstoff = kraftstoff;
            car.Leistung = leistung;
            car.Hubraum = hubraum;
            car.Zylinder = zylinder;
            car.Verbrauch = new Model.Verbrauch() { Innerorts = verbrauchInnerorts, Ausserorts = verbrauchAusserorts };
            car.Farbe = farbe;

            return car;
        }

        private void btnNewCar_Click(object sender, RoutedEventArgs e)
        {
            if (this.ContinueCheck(ref this.carChangesSaved))
            {
                this.CurrentlyActiveCar = new Model.Auto() { Id = int.MinValue };
                this.grdCarEdit.IsEnabled = true;
                this.carChangesSaved = false;
                this.btnCarAbort.IsEnabled = true;
                this.btnCarDelete.IsEnabled = false;
                this.btnCarSaveChanges.IsEnabled = true;
            }
        }

        private void btnCarDelete_Click(object sender, RoutedEventArgs e)
        {
            if (this.currentlyActiveCar != null)
            {
                if (this.ContinueCheck(ref this.carChangesSaved))
                {
                    var res = MessageBox.Show("Möchten Sie das Auto wirklich löschen?", "Auto löschen", MessageBoxButton.YesNo,
                        MessageBoxImage.Warning, MessageBoxResult.No);

                    if (res == MessageBoxResult.Yes)
                    {
                        if (this.fachkonzept.LoescheAuto(this.currentlyActiveCar.Id))
                        {
                            //this.InformationDialog("Das Auto wurde erfolgreich gelöscht.", "Löschen erfolgreich");

                            //this.RefreshCarList();
                            this.carChangesSaved = true;
                            this.AktualisiereAutoDaten();
                            return;
                        }
                    }
                    else
                    {
                        return;
                    }
                }
            }

            this.InformationDialog("Das Auto konnte nicht gelöscht werden.", "Löschen fehlgeschlagen");
        }

        private void btnCarSaveChanges_Click(object sender, RoutedEventArgs e)
        {
            Model.Auto car = this.BuildCar();

            if (this.CurrentlyActiveCar != null && !this.CurrentlyActiveCar.Id.Equals(int.MinValue))
            {
                if (this.fachkonzept.BearbeiteAuto(this.CurrentlyActiveCar.Id, car))
                {
                    this.carChangesSaved = true;
                    //this.RefreshCarList(car);
                    this.AktualisiereAutoDaten(car);
                    //this.InformationDialog("Die Änderungen am Auto wurden erfolgreich übernommen.", "Speichern erfolgreich");
                }
                else
                {
                    this.InformationDialog("Die Änderungen am Auto konnten nicht übernommen werden.", "Speichern fehlgeschlagen");
                }
            }
            else
            {
                if (this.fachkonzept.NeuesAuto(car))
                {
                    this.carChangesSaved = true;
                    this.CurrentlyActiveCar = null;
                    this.SelectNewCar(car);
                    //this.InformationDialog("Das Auto wurde erfolgreich gespeichert.", "Speichern erfolgreich");
                }
                else
                {
                    this.InformationDialog("Das Auto konnte nicht gespeichert werden.", "Speichern fehlgeschlagen");
                }
            }
        }

        private void SelectNewCar(Model.Auto car)
        {
            if (car != null)
            {
                if (car.Modell != null)
                {
                    this.SelectHersteller(car.Modell.Hersteller);
                }
                this.SelectModell(car.Modell);
                //this.RefreshCarList(car);
                this.AktualisiereAutoDaten(car);
            }
        }

        private void btnCarAbort_Click(object sender, RoutedEventArgs e)
        {
            if (this.ContinueCheck(ref this.carChangesSaved))
            {
                this.carChangesSaved = true;
                this.CurrentlyActiveCar = this.CurrentlyActiveCar;
            }
        }
        #endregion

        #region Implement IUserInterface
        public void DisplayException(Exception ex)
        {
            MessageBox.Show("Die Anwendung muss beendet werden.\n\nFehler:\n" + ex.Message, "Schwerwiegender Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            Application.Current.Shutdown();
        }
        #endregion

        private void InformationDialog(string message, string caption)
        {
            MessageBox.Show(message, caption, MessageBoxButton.OK,
                MessageBoxImage.Information, MessageBoxResult.OK);
        }

        private bool ContinueCheck(ref bool changesSaved)
        {
            if (!changesSaved)
            {
                var res = MessageBox.Show("Es sind noch nicht gespeicherte Daten vorhanden.\n" +
                "Möchten Sie die nicht gespeicherten Änderungen verwerfen?", "Nicht Gespeicherte Daten", MessageBoxButton.YesNo,
                MessageBoxImage.Warning, MessageBoxResult.No);

                if (res == MessageBoxResult.No)
                {
                    return false;
                }
            }

            changesSaved = true;
            return true;
        }
    }
}
